﻿#pragma once
#include <sfse_common/Utilities.h>

#include "sfse/GameSettings.h"

class qqSetting
{
public:
    virtual ~qqSetting();
    virtual void Unk_01();
    virtual void Unk_02();

    enum Type
    {
        kBinary,        // b
        kChar,        // c
        kUChar,        // h
        kInt,        // i
        kUInt,        // u
        kFloat,        // f
        kString,        // s/S
        kRGB,        // r
        kRGBA,        // a
        kNone
    };

    union Data
    {
        s8 c;
        bool b;
        float f;
        s8 h;
        s32 i;
        char* s;
        u32 u;
        u32 r; // rgb
        u32 a; // rgba
    };

    Data data; // 08
    Data defaultData; // 10
    char* name; // 18

    Type GetType() const noexcept
    {
        if (name)
        {
            switch (name[0])
            {
            case 'b':
                return kBinary;
            case 'c':
                return kChar;
            case 'h':
                return kUChar;
            case 'i':
                return kInt;
            case 'u':
                return kUInt;
            case 'f':
                return kFloat;
            case 's':
            case 'S':
                return kString;
            case 'r':
                return kRGB;
            case 'a':
                return kRGBA;
            default:
                return kNone;
            }
        }
        return kNone;
    }

    void SetDouble(double a_value);
    void SetU32(u32 a_value);
    void SetS32(s32 a_value);
};

template <typename T>
class qqSettingCollection
{
public:
    virtual ~qqSettingCollection();

    virtual void Add(T* apSetting) = 0; // 01
    virtual void Remove(T* apSetting) = 0; // 02
    virtual void Unk_03() = 0; // 03
    virtual void WriteSetting(T& arSetting) = 0; // 04
    virtual void ReadSetting(T& arSetting) = 0; // 05
    virtual bool Open(); // 06
    virtual bool Close(); // 07
    virtual bool ReadSettingsFromProfile(); // 08
    virtual void Unk_09(); // 09
    virtual bool WriteSettings(); // 0A
    virtual bool ReadSettings(); // 0B

    class CollectionMap
    {
    };

    char pSettingFile[260]; // 008
    u32 pad10C; // 10C
    void* pHandle; // 110
    void* SettingsA; // 118
    u64 unk128; // 128
    u64 unk130; // 130
};

template <typename T>
class SettingCollectionMap : public qqSettingCollection<T>
{
public:
    virtual ~SettingCollectionMap();
};


class GameSettingCollection : public SettingCollectionMap<qqSetting>
{
public:
    virtual ~GameSettingCollection();
};

typedef qqSetting* (*_GetSetting)(void* collectionMap, const char* name);
extern RelocAddr<_GetSetting> GetSetting;

typedef void* (*_SettingUpdated)(qqSetting* setting);
extern RelocAddr<_SettingUpdated> SettingUpdated;
